import dbm
import os

import pytest

from storage.kvstore.dbm import DbmKVStore


def test_get_put_dbm(kv_path):
    store = DbmKVStore(kv_path)
    with store.tx():
        store.put(b'key', b'value')
    with store.tx():
        assert store.get(b'key') == b'value'


def test_getitem_setitem_dbm(kv_path):
    store = DbmKVStore(kv_path)
    with store.tx():
        store[b'key'] = b'value'
    with store.tx():
        assert store[b'key'] == b'value'


def test_delete_dbm(kv_path):
    store = DbmKVStore(kv_path)
    with store.tx():
        store.put(b'key', b'value')

    with store.tx():
        del store[b'key']

    with store.tx():
        assert store.get(b'key') is None


@pytest.mark.benchmark
@pytest.mark.skipif(os.name == 'nt', reason='windows dumb implementation is too slow')
def test_benchmark_read_dbm(benchmark,kv_path, insert_keys, get_keys):
    db = dbm.open(str(kv_path), 'n')
    for k in insert_keys:
        db[k] = os.urandom(8)

    def benchmark_dbm_get():
        nonlocal db
        for k in get_keys:
            _ = db.get(k)

    benchmark(benchmark_dbm_get)


@pytest.mark.benchmark
@pytest.mark.skipif(os.name == 'nt', reason='windows dumb implementation is too slow')
def test_benchmark_write_dbm(benchmark,kv_path, insert_keys):
    def benchmark_func():
        db = dbm.open(str(kv_path), 'n')
        for k in insert_keys:
            db[k] = os.urandom(8)

    benchmark(benchmark_func)
